﻿#define _CRT_SECURE_NO_WARNINGS

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

//qsort库函数
//底层排序是 快速排序
//可以排序任意类型的数据

//void qsort(
//	void* base,//base 指向了要排序的数组的第一个元素
//	size_t num,//base指向的数组的元素个数
//	size_t size,//base指向的数组的元素的大小

//	int (*compar)(const void* p1, const void* p2)//函数指针--指针指向的函数是用来比较数组中的2个元素
//		  );

//void Super_Bubble_sort(void* base, size_t sz, size_t width, int (*Cmp)(const void* p1, const void* p2));
////
//
//void Swap(char* buf1, char* buf2, size_t width) {
//
//	int i = 0;
//	for (i = 0; i < width; i++) {
//
//		char tmp = *buf1;
//		*buf1 = *buf2;
//		*buf2 = tmp;
//		buf1++;
//		buf2++;
//	}
//}
//
//void Print_arr(int* arr, int sz) {
//
//	int i = 0;
//	for (i = 0; i < sz; i++) {
//
//		printf("%d ", arr[i]);
//	}
//	printf("\n");
//}
//
//int Cmp_int(const void* p1, const void* p2){
//
//	return *(int*)p1 - *(int*)p2;//升序排序，若交换p1和p2交换位置则为降序
//}
//
//void Test1(){
//
//	int arr[10] = { 3,1,5,2,4,6,8,7,0,9 };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//
//	Print_arr(arr, sz);
//	Super_Bubble_sort(arr, sz, sizeof(arr[0]), Cmp_int);
//	Print_arr(arr, sz);
//}
//
//
//struct Stu{
//
//	char name[20];
//	int age;
//};
//
////怎么比较两个结构体数据？
//
////1.按照年龄比较
//int Cmp_stu_by_age(const void* p1, const void* p2){
//
//	return ((struct Stu*)p1)->age - ((struct Stu*)p2)->age;
//}
//
//void Test2(){
//
//	struct Stu arr[] = { { "zhangsan", 20},{"lisi",38} ,{"wangwu",18} };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	Super_Bubble_sort(arr, sz, sizeof(arr[0]), Cmp_stu_by_age);
//	for (int i= 0; i < sz; i++){
//
//		printf("%s %d\n", arr[i].name, arr[i].age);
//	}
//
//}
// 
////2.按照名字比较
////两个字符串不能使用> < ==
////而是使用库函数stcmp -string compare
//// int strcmp (const char* str1,const char* str2)
////比较字符串  其实是按照对应位置上的字符的ASCII码值的大小比较的
//int Cmp_stu_by_name(const void* p1, const void* p2){
//
//	return strcmp(((struct Stu*)p1)->name, ((struct Stu*)p2)->name);
//}
//
//void Test3(){
//
//	struct Stu arr[] = { { "zhangsan", 20},{"lisi",38} ,{"wangwu",18} };
//	int sz = sizeof(arr) / sizeof(arr[0]);
//	Super_Bubble_sort(arr, sz, sizeof(arr[0]), Cmp_stu_by_name);
//	for (int i = 0; i < sz; i++) {
//
//		printf("%s %d\n", arr[i].name, arr[i].age);
//	}
//}
//
//void Super_Bubble_sort(void* base, size_t sz, size_t width, int (*Cmp)(const void* p1, const void* p2)) {
//
//	int i = 0;
//	for (i = 0; i < sz - 1; i++) 
//	{
//
//		int j = 0;
//		for (j = 0; j < sz - 1 - i; j++) {
//
//			if (Cmp((char*)base + j * width, (char*)base + (j + 1) * width) > 0) {
//
//				Swap((char*)base + j * width, (char*)base + (j + 1) * width, width);
//			}
//
//		}
//	}
//}
//
//int main2()
//{
//	//测试qsort函数排序 整形数据的
//	//Test1();
//	
//	//测试qsort函数排序 结构体数据的
//	//1.按照年龄比较
//	//Test2();
//	
//	//2.按照名字比较
//	//Test3();
//
//	return 0;
//}


//sizeof操作符
//int main()
//{
//	int a = 10;
//	printf("%zd\n", sizeof(a));//4
//	printf("%zd\n", sizeof(int));//4
//	printf("%zd\n", sizeof a);//4   //这里可以省略（）
//	//printf("%zd\n", sizeof int);//error
//
//	int arr1[4] = { 0 };
//	char arr2[4] = { 0 };
//	printf("%zd\n", sizeof(arr1));//16
//	printf("%zd\n", sizeof(int [4]));//16
//	printf("%zd\n", sizeof(arr2));//4
//	printf("%zd\n", sizeof(char [4]));//4
//
//	return 0;
//}


//strlen 是C语⾔库函数，功能是求字符串⻓度
//int main()
//{
//	char arr1[3] = { 'a', 'b', 'c' };
//	char arr2[] = "abc";
//	printf("%zd\n", strlen(arr1));//随机值
//	printf("%zd\n", strlen(arr2));//3
//
//	printf("%zd\n", sizeof(arr1));//3
//	printf("%zd\n", sizeof(arr2));//4
//	return 0;
//}

//sizeof 和 strlen的对⽐
//sizeof
//1. sizeof是操作符
//2. sizeof计算操作数所占内存的⼤⼩，单位是字节
//3. 不关注内存中存放什么数据
//strlen
//1. strlen是库函数，使⽤需要包含头⽂件 string.h
//2. srtlen是求字符串⻓度的，统计的是 \0 之前字符的隔个数
//3. 关注内存中是否有 \0 ，如果没有 \0 ，就会持续往后找，可能会越界





//数组和指针笔试题解析

//int main()
//{
	//⼀维数组
	//int a[] = { 1,2,3,4 };
	//printf("%zd\n", sizeof(a));//16
	//printf("%zd\n", sizeof(a + 0));//4/8
	//printf("%zd\n", sizeof(*a));//4
	//printf("%zd\n", sizeof(a + 1));//4/8
	//printf("%zd\n", sizeof(a[1]));//4
	//printf("%zd\n", sizeof(&a));//4/8
	//printf("%zd\n", sizeof(*&a));//16
	//printf("%zd\n", sizeof(&a + 1));//4/8
	//printf("%zd\n", sizeof(&a[0]));//4/8
	//printf("%zd\n", sizeof(&a[0] + 1));//4/8


	//字符数组
	//char arr[] = { 'a','b','c','d','e','f' };
	//printf("%zd\n", sizeof(arr));//6
	//printf("%zd\n", sizeof(arr + 0));//4/8	
	//printf("%zd\n", sizeof(*arr));//1
	//printf("%zd\n", sizeof(arr[1]));//1
	//printf("%zd\n", sizeof(&arr));//4/8
	//printf("%zd\n", sizeof(&arr + 1));//4/8
	//printf("%zd\n", sizeof(&arr[0] + 1));//4/8


	//char arr[] = "abcdef";
	//printf("%d\n", sizeof(arr));//7
	//printf("%d\n", sizeof(arr + 0));//4/8
	//printf("%d\n", sizeof(*arr));//1
	//printf("%d\n", sizeof(arr[1]));//1
	//printf("%d\n", sizeof(&arr));//4/8
	//printf("%d\n", sizeof(&arr + 1));//4/8
	//printf("%d\n", sizeof(&arr[0] + 1));//4/8


	//char arr[] = "abcdef";
	//printf("%d\n", strlen(arr));//6
	//printf("%d\n", strlen(arr + 0));//6
	//printf("%d\n", strlen(*arr));//err
	//printf("%d\n", strlen(arr[1]));//err
	//printf("%d\n", strlen(&arr));//6
	// printf("%d\n", strlen(&arr + 1));//随机值
	//printf("%d\n", strlen(&arr[0] + 1));//5


	//char* p = "abcdef";
	//printf("%d\n", strlen(p));//6
	//printf("%d\n", strlen(p + 1));//5
	//printf("%d\n", strlen(*p));//err
	//printf("%d\n", strlen(p[0]));//err
	//printf("%d\n", strlen(&p));//6
	//printf("%d\n", strlen(&p + 1));//随机值
	//printf("%d\n", strlen(&p[0] + 1));//5


	//⼆维数组
	//int a[3][4] = { 0 };
	//printf("%d\n", sizeof(a));//48
	//printf("%d\n", sizeof(a[0][0]));//4
	//printf("%d\n", sizeof(a[0]));//16
	//printf("%d\n", sizeof(a[0] + 1));//4/8
	//printf("%d\n", sizeof(*(a[0] + 1)));//4
	//printf("%d\n", sizeof(a + 1));//4/8
	//printf("%d\n", sizeof(*(a + 1)));//16
	//printf("%d\n", sizeof(&a[0] + 1));//4/8
	//printf("%d\n", sizeof(*(&a[0] + 1)));//16
	//printf("%d\n", sizeof(*a));//16
	//printf("%d\n", sizeof(a[3]));//16


	//数组名的意义：
	//	1. sizeof(数组名)，这⾥的数组名表⽰整个数组，计算的是整个数组的⼤⼩。
	//	2. & 数组名，这⾥的数组名表⽰整个数组，取出的是整个数组的地址。
	//	3. 除此之外所有的数组名都表⽰⾸元素的地址

//	return 0;
//}


//指针运算笔试题解析
//1
//int main()
//{
//	int a[5] = { 1, 2, 3, 4, 5 };
//	int* ptr = (int*)(&a + 1);
//	printf("%d,%d", *(a + 1), *(ptr - 1));//2//5
//	return 0;
//}
//
//2.
//在X86环境下
//假设结构体的⼤⼩是20个字节
//程序输出的结构是啥？
//struct Test
//{
//	int Num;
//	char* pcName;
//	short sDate;
//	char cha[2];
//	short sBa[4];
//}*p = (struct Test*)0x100000;
//
//int main()
//{
//	printf("%p\n", p + 0x1);//00100014
//	printf("%p\n", (unsigned long)p + 0x1);//00100001
//	printf("%p\n", (unsigned int*)p + 0x1);//00100004
//	return 0;
//}
//
//
//3.
//int main()
//{
//	int a[3][2] = { (0, 1), (2, 3), (4, 5) };
//	int* p;
//	p = a[0];
//	printf("%d", p[0]);//1//3
//	return 0;
//}
//
//
//4.
//假设环境是x86环境，程序输出的结果是啥？
//int main()
//{
//	int a[5][5];
//	int(*p)[4];
//	p = a;
//	printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
	//10000000 00000000 00000000 00000100
	//11111111 11111111 11111111 11111011
	//11111111 11111111 11111111 11111100
	//FF FF FF FC
	//-4
//	return 0;
//}
//
//
//5.
//int main()
//{
//	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
//	int* ptr1 = (int*)(&aa + 1);
//	int* ptr2 = (int*)(*(aa + 1));
//	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));//10 //5
//	return 0;
//}
//
//
//6.
//int main()
//{
//	char* a[] = { "work","at","alibaba" };
//	char** pa = a;
//	pa++;
//	printf("%s\n", *pa);//at
//	return 0;
//}
//
//7.
//int main()
//{
//	char* c[] = { "ENTER","NEW","POINT","FIRST" };
//	char** cp[] = { c + 3,c + 2,c + 1,c };
//	char*** cpp = cp;
//	printf("%s\n", **++cpp);//POINT
//	printf("%s\n", *-- * ++cpp + 3);//ER
//	printf("%s\n", *cpp[-2] + 3);//ST
//	printf("%s\n", cpp[-1][-1] + 1);//EW
//	return 0;
//}




